package insight.sm.db;

import insight.sm.annotations.Column;
import insight.sm.annotations.Table;
import insight.sm.delegates.ReflectionDelegate;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

public class ResultSetMapper<T> {
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> mapRersultSetToObject1(ResultSet rs, Class outputClass) throws NoSuchMethodException {
		List<T> outputList = null;
		try {
			// make sure resultset is not null
			if (rs != null) {
				// check if outputClass has 'Entity' annotation
				if (outputClass.isAnnotationPresent(Table.class)) {
					// get the resultset metadata
					// ResultSetMetaData rsmd = rs.getMetaData();
					// get all the attributes of outputClass
					// Field[] fields = outputClass.getDeclaredFields();
					Field[] fields = ReflectionDelegate.getAnnotatedFields(
							outputClass, Column.class);
					
					java.util.Date defaultValue = null;
					DateConverter converter = new DateConverter(defaultValue);
					ConvertUtils.register(converter, java.util.Date.class);
					
					while (rs.next()) {
						T bean = (T) outputClass.newInstance();
						for (Field field : fields) {
							if (field.isAnnotationPresent(Column.class)) {
								String fieldName = field.getAnnotation(
										Column.class).name();
								Object value = rs.getObject(fieldName);
								//ReflectionDelegate.getSetterMethod(field).invoke(bean, value);
								//PropertyUtils.setProperty(bean, field.getName(),value);
								BeanUtils.setProperty(bean, field.getName(), value);
								//System.out.println(bean);

							}
						}

						if (outputList == null) {
							outputList = new ArrayList<T>();
						}
						outputList.add(bean);
					}

				} else {
					// throw some error
				}
			} else {
				return null;
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return outputList;
	}
}